from odoo import fields, models, api
from odoo.exceptions import UserError
from odoo.addons.basic_configuration.config.env_config import switch_env
from odoo.http import request
from odoo.addons.rp_customer_management.functions.customer_functions import CustomerFunctions
from odoo.addons.basic_configuration.functions.common_utils_fc import CommonUtils
from odoo.addons.rp_finance_management.functions.rp_finance_related_func import RpFinanceRelatedFunc


class RpShipOrderActionPayTran(models.TransientModel):
    _name = 'rp.ship.order.action.pay.tran'
    _description = '订单支付'
    _rec_name = 'code'

    def _default_code(self):
        records = self.env['rp.ship.order.action.pay.tran'].search([])
        return "SPT" + str(len(records) + 1).zfill(3)

    code = fields.Char(string='序列号', default=_default_code, index=True, readonly=True)
    operation_person = fields.Many2one(string='操作人', comodel_name='res.users', default=lambda self: self.env.user)
    currency_id = fields.Many2one(string='货币单位', comodel_name='res.currency', default=lambda self: self.env.company.currency_id)
    pay_time = fields.Datetime(string='支付时间', default=fields.Datetime.now(), index=True)
    customer_id = fields.Many2one(string='客户', comodel_name='rp.customer')
    order_code = fields.Char(string='订单')
    order_total_price = fields.Float(string='订单总价', digits=(12, 5))
    balance_tag = fields.Boolean(string='余额支付', default=False)
    stripe_tag = fields.Boolean(string='Stripe支付', default=False)
    balance_price = fields.Float(string='余额支付金额', digits=(12, 5))
    stripe_price = fields.Float(string='Stripe支付金额', digits=(12, 5))
    qr_code = fields.Binary(string='二维码')

    """
    Native
    """

    @api.model
    def default_get(self, fields_list):
        res = super(RpShipOrderActionPayTran, self).default_get(fields_list)
        if 'customer_id' in self.env.context:
            res['customer_id'] = self.env.context['customer_id']
        if 'order_total_price' in self.env.context:
            res['order_total_price'] = self.env.context['order_total_price']
        if 'order_code' in self.env.context:
            res['order_code'] = self.env.context['order_code']
        return res

    @api.constrains('stripe_tag', 'balance_tag', 'stripe_price', 'balance_price')
    def constrains_tag_price(self):
        for record in self:
            customer_balance = record.customer_id.rp_customer_balance_id.total_balance
            if not record.stripe_tag and not record.balance_tag:
                raise UserError('请至少选择一种支付方式！')
            if record.stripe_tag:
                if record.stripe_price == 0:
                    raise UserError('您选择了Stripe支付，请填写金额！')
                if not record.balance_tag and record.stripe_price != record.order_total_price:
                    raise UserError('支付金额有误，请重新填写！')
            if record.balance_tag:
                if record.balance_price == 0:
                    raise UserError('您选择了余额支付，请填写金额！')
                if record.balance_price > customer_balance:
                    raise UserError('您填写的余额金额超出了客户余额！')
                if not record.stripe_tag and record.balance_price != record.order_total_price:
                    raise UserError('支付金额有误，请重新填写！')
            if record.balance_tag and record.stripe_tag:
                if round(record.order_total_price, 3) != round(record.balance_price + record.stripe_price, 3):
                    raise UserError('支付金额有误，请重新填写！')

    """
    Onchange
    """

    @api.onchange('stripe_tag', 'balance_tag')
    def onchange_price_tag(self):
        """
        清空价格选项
        """
        if not self.stripe_tag:
            self.update({'stripe_price': False})
        if not self.balance_tag:
            self.update({'balance_price': False})

    @api.onchange('balance_price', 'stripe_price', 'stripe_tag')
    def onchange_price(self):
        if self.balance_tag and self.stripe_tag:
            self.update({'stripe_price': self.order_total_price - self.balance_price})

    """
    Button Function
    """

    def pay_now(self):
        """
        支付
        """

        # 判断是否已经支付
        rp_ship_order_id = self.env['rp.ship.order'].search([('code', '=', self.order_code)])
        if rp_ship_order_id.state in ['done', 'invoiced']:
            raise UserError('订单已支付，请勿重复支付，取消即可！')
        # 给订单生成支付链接
        link = '{}:{}/qr_code/pay?order_id={}&balance_price={}&stripe_price={}&total_price={}'.format(switch_env.get('env').get('ip'), switch_env.get('env').get('port'), rp_ship_order_id.id
                                                                                                      , self.balance_price, self.stripe_price, self.order_total_price)
        rp_ship_order_id.write({'pay_link': link})
        # 更新支付单信息
        rp_ship_order_payment_id = self.env.context.get('rp_ship_order_payment_id')
        rp_ship_order_payment_id = self.env['rp.payment'].search([('id', '=', rp_ship_order_payment_id)])
        rp_ship_order_payment_id = RpFinanceRelatedFunc(self.env).update_payment(rp_ship_order_id, rp_ship_order_payment_id, self.balance_tag, self.stripe_tag, self.balance_price, self.stripe_price, self.order_total_price)
        rp_ship_order_payment_id.write({'pay_url': link})
        rp_ship_order_id.write({'click_pay_flag': True})  # 修改触发支付状态为True，用户显示支付单
        # stripe支付
        if self.stripe_tag:
            stripe_price = self.stripe_price
            #  进行Stripe支付
            pay_url = RpFinanceRelatedFunc(self.env).stripe_pay(pay_price=stripe_price, request=request, way="odoo", payment_code=rp_ship_order_payment_id.code)
            # 跳转到指定页面
            return {
                'type': 'ir.actions.act_url',
                'url': pay_url,
                'target': 'self'
            }
        # 只存在余额支付
        if self.balance_tag and not self.stripe_tag:
            # 扣除金额
            customer_id = rp_ship_order_payment_id.customer_id
            rp_customer_id = self.env['rp.customer'].search([('id', '=', customer_id.field_record_id)])
            # 核算用户余额
            CustomerFunctions(request.env).pay_out(rp_customer_id.rp_customer_balance_id, self.balance_price)
            rp_ship_order_id.with_context({'payment_code': rp_ship_order_payment_id.code}).action_for_pay()

    def gene_qrcode(self):
        """
        生成二维码
        """
        # 校验数据
        self.constrains_tag_price()
        if self.balance_price and not self.stripe_price:
            raise UserError('只有余额支付，无需生成二维码，后台直接扣减即可！')
        rp_ship_order_id = self.env['rp.ship.order'].search([('code', '=', self.order_code)])
        if rp_ship_order_id.state == 'done':
            raise UserError('订单已经支付完成，二维码无法生成！')
        link = '{}:{}/qr_code/pay?order_id={}&balance_price={}&stripe_price={}&total_price={}'.format(switch_env.get('env').get('ip'), switch_env.get('env').get('port'), rp_ship_order_id.id
                                                                                                      , self.balance_price, self.stripe_price, self.order_total_price)
        # 订单生成支付链接,支付单生成链接
        rp_ship_order_id.write({'pay_link': link})
        rp_ship_order_payment_id = self.env['rp.payment'].search([('advance_document_id.field_record_id', '=', rp_ship_order_id.id), ('advance_document_id.field_name_id.model', '=', 'rp.ship.order')])
        rp_ship_order_payment_id.write({'pay_url': link})
        img_data = CommonUtils().generate_qr_code(link=link)
        # 展示图片
        self.write({'qr_code': img_data})
        # 返回视图
        return {
            'type': 'ir.actions.act_window',
            'res_model': 'rp.ship.order.action.pay.tran',
            'view_mode': 'form',
            'res_id': self.id,  # 保持当前记录
            'name': '订单支付向导',
            'context': {'show_display': True},
            'target': 'new',  # 在当前窗口中显示
        }
